#ifndef CSR_H
#define CSR_H

#include <stdint.h>

#define CSR_MSTATUS 0x300   // 机器模式状态寄存器
#define CSR_MIE 0x304       // 机器模式中断使能寄存器
#define CSR_MTVEC 0x305     // 机器模式中断向量表基址寄存器
#define CSR_MSCRATCH 0x340  // 机器模式临时寄存器
#define CSR_MEPC 0x341      // 机器模式异常程序计数器
#define CSR_MCAUSE 0x342    // 机器模式异常原因
#define CSR_MTVAL 0x343     // 机器模式异常值
#define CSR_MIP 0x344       // 机器模式中断挂起寄存器
#define CSR_MVENDORID 0xf11 // 机器模式厂商ID
#define CSR_MARCHID 0xf12   // 机器模式架构ID
#define CSR_MIMPID 0xf13    // 机器模式实现ID
#define CSR_MHARTID 0xf14   // 机器模式硬件线程ID
#define CSR_MTIMECMP 0x7c0  // 机器模式时间比较寄存器
#define CSR_MTIME 0xbff     // 机器模式时间寄存器

#define MSTATUS_MIE 0x8     // 全局中断使能位
#define MSTATUS_MPP 0x1800  // 机器模式优先级
#define MSTATUS_MPIE 0x80   // 机器模式中断使能位
#define MSTATUS_MPRV 0x10   // 机器模式访问权限位
#define MSTATUS_SUM 0x40000 // 用户模式访问权限位
#define MSTATUS_SIE 0x2     // 用户模式中断使能位
#define MSTATUS_SPIE 0x20   // 用户模式中断使能位
#define MSTATUS_SPP 0x1000  // 用户模式优先级
#define MSTATUS_FS 0x3      // 浮点数状态
#define MSTATUS_XS 0xc      // 扩展状态
#define MSTATUS_SD 0x80000000 // 禁用延迟槽

#define MIE_MTIE    0x80    //  定时器中断使能
#define MIE_MEIE    0x800   //  外部中断使能
#define MIE_MSIE    0x8     //  软中断使能

#define MIP_MTIP    0x80    //  定时器中断挂起
#define MIP_MEIP    0x800   //  外部中断挂起
#define MIP_MSIP    0x8     //  软中断挂起

#define MCAUSE_INT 0x80000000 // 中断
#define MCAUSE_EXC 0x7fffffff // 异常



struct csr{
    uint32_t mstatus;
    uint32_t mie;
    uint32_t mtvec;
    uint32_t mscratch;
    uint32_t mepc;
    uint32_t mcause;
    uint32_t mtval;
    uint32_t mip;
    uint32_t mvendorid;
    uint32_t marchid;
    uint32_t mimpid;
    uint32_t mhartid;
};

void csr_init(struct csr *csr);
uint32_t export_read(uint32_t addr);
void export_write(uint32_t addr,uint32_t data);
uint32_t csr_read(struct csr *csr,uint32_t csr_addr);
int csr_write(struct csr *csr,uint32_t csr_addr,uint32_t data);

#endif
